﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Text.Json;
using System.Threading;

namespace PNet
{
    public static class IOCPTool
    {
        public enum LogColor
        {
            None,
            Red,
            Green,
            Blue,
            Cyan,
            Magenta,
            Yellow
        }

        public static Action<LogColor> LogFunc;
        public static Action<LogColor> WarningFunc;
        public static Action<LogColor> ErrorFunc;
        public static Action<LogColor, string> ColorLogFunc;

        #region 数据处理

        /// <summary>
        /// 解析数据，将数据头和数据体分离
        /// </summary>
        /// <param name="readBytes"></param>
        /// <returns></returns>
        public static byte[] SplitLogicByte(ref List<byte> readBytes)
        {
            byte[] buffer = null;
            if (readBytes.Count > 4) //需要判断是否满足头文件长度读取需求
            {
                byte[] bytes = readBytes.ToArray(); //转换为字节数组
                int len = BitConverter.ToInt32(bytes, 0); //解析前4个字节的头文件，得到当前字节的长度
                if (readBytes.Count >= len + 4) //判断当前接收的List中的字节长度是否大于 + 需要解析的字节长度+表示长度的4个字节
                {
                    buffer = new byte[len];
                    Buffer.BlockCopy(bytes, 4, buffer, 0, len); //大于说明可以解析，将当前的len长度的字节，从bytes中的第4个位置
                                                               //开始解析len的长度到buffer字节数组中
                    readBytes.RemoveRange(0, len + 4);        //解析完成后，让当前包体长度+表示字节长度的数据从list中移除
                }
            }

            return buffer;
        }

        #endregion

        /*
        public static byte[] Serialize<T>(T msg) where T : IOCPMsg, new()
        {
            byte[] data = null;
            try
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(ms, msg);
                    ms.Seek(0, SeekOrigin.Begin);
                    data = ms.ToArray();
                }
            }
            catch (SerializationException e)
            {
                LogError("Serialize failed:" + e.Message);
            }
            return data;
        }

        public static T DeSerialize<T>(byte[] bytes) where T : IOCPMsg,new()
        {
            T msg = null;
            try
            {
                using (MemoryStream ms = new MemoryStream(bytes))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    msg = (T)bf.Deserialize(ms);
                }
            }
            catch (SerializationException e)
            {
                LogError("DeSerialize failed {0}, byte length:", e.Message, bytes.Length);
            }
            return msg;
        }
        */

        public static byte[] Serialize<T>(T msg) where T : new()
        {
            return JsonSerializer.SerializeToUtf8Bytes(msg);
        }
        public static T DeSerialize<T>(byte[] bytes) where T : new()
        {
            return JsonSerializer.Deserialize<T>(bytes);
        }

        /// <summary>
        /// 将需要发送的数据体，加上长度信息
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static byte[] PackIenInfo(byte[] bytes) 
        {
            byte[] data = new byte[bytes.Length+4];
            byte[] head = BitConverter.GetBytes(bytes.Length);
            head.CopyTo(data, 0);
            bytes.CopyTo(data, 4);
            return data;
        }

        public static void Log(string msg, params object[] args)
        {
            msg = string.Format(msg, args);
            if (LogFunc != null)
            {
                LogFunc(LogColor.Magenta);
            }
            else
            {
                ConsoleLog(msg, LogColor.None);
            }
        }
        public static void LogWarning(string msg, params object[] args)
        {
            msg = string.Format(msg, args);
            if (WarningFunc != null)
            {
                WarningFunc(LogColor.Magenta);
            }
            else
            {
                ConsoleLog(msg, LogColor.Yellow);
            }
        }
        public static void LogError(string msg, params object[] args)
        {
            msg = string.Format(msg, args);
            if (ErrorFunc != null)
            {
                ErrorFunc(LogColor.Red);
            }
            else
            {
                ConsoleLog(msg, LogColor.None);
            }
        }
        public static void ColorLog(LogColor color,string msg, params object[] args)
        {
            msg = string.Format(msg, args);
            if (ColorLogFunc != null)
            {
                ColorLogFunc(LogColor.Red,msg);
            }
            else
            {
                ConsoleLog(msg, color);
            }
        }
        public static void ConsoleLog(string msg,LogColor color)
        {
            int mainThreadID = Thread.CurrentThread.ManagedThreadId;
            msg = string.Format("ThreadID:{0}--{1}", mainThreadID, msg);
            switch (color)
            {
         
                case LogColor.Red:
                    Console.ForegroundColor = ConsoleColor.DarkRed;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.Green:
                    Console.ForegroundColor = ConsoleColor.Green;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.Blue:
                    Console.BackgroundColor = ConsoleColor.Blue;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.Cyan:
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.Magenta:
                    Console.ForegroundColor = ConsoleColor.Magenta;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.Yellow:
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
                case LogColor.None:
                    Console.ForegroundColor = ConsoleColor.White;
                    Console.WriteLine(msg);
                    Console.ForegroundColor = ConsoleColor.Gray;
                    break;
           
            }

        }

    }
}
